home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
what.zip
/
HELPEX.C_
/
HELPEX.bin
Wrap
Text File
|
1992-08-06
|
20KB
|
692 lines
/****************************************************************************
PROGRAM: HelpEx.c
PURPOSE: Illustrates calls to WinHelp and context-sensitive help.
HelpEx loads library MenuHook, which detects F1 keystrokes in
the HelpEx application menus.
FUNCTIONS:
WinMain() - Calls initialization function, processes message loop.
InitApplication() - Initializes window data and registers window class.
InitInstance() - Saves instance handle and creates main window.
MainWndProc() - Processes window messages.
About() - Processes messages for "About" dialog box.
MakeHelpPathName() - Derives path name of help file.
****************************************************************************/
#include <windows.h>
#include "helpex.h"
#include "helpids.h"
HWND hWnd; /* Handle to main window */
HANDLE hInst; /* Handle to instance data*/
FARPROC lpFilterFunc;
BOOL bHelp = FALSE; /* Help mode flag; TRUE = "ON"*/
DWORD dwCurrentHelpId = HELPID_NONE; /* Current help context for menus and dialogs */
HCURSOR hHelpCursor; /* Cursor displayed when in help mode*/
char szHelpFileName[EXE_NAME_MAX_SIZE+1]; /* Help file name*/
HANDLE hAccTable; /* handle to accelerator table */
HMENU hMenuFile, hMenuEdit, hMenuHelp;
void MakeHelpPathName(char*); /* Function deriving help file path */
int FAR PASCAL FilterFunc(int, WORD, DWORD); /* Filter function to detect F1*/
BOOL MyWinHelp(HWND, LPSTR, WORD, DWORD);
void StartDialog(FARPROC, WORD);
void DisplayError(WORD);
/****************************************************************************
FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
PURPOSE: Calls initialization function, processes message loop.
****************************************************************************/
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
MSG msg;
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
while (GetMessage(&msg, NULL, NULL, NULL)) {
/* Only translate message if it is not an accelerator message */
if (!TranslateAccelerator(hWnd, hAccTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (msg.wParam);
}
/****************************************************************************
FUNCTION: InitApplication(HANDLE)
PURPOSE: Initializes window data and registers window class.
RETURNS: Status of RegisterClass() call.
****************************************************************************/
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
WNDCLASS wc;
wc.style = NULL;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = COLOR_WINDOW+1;
wc.lpszMenuName ="HelpexMenu";
wc.lpszClassName = "HelpexWClass";
return (RegisterClass(&wc));
}
/****************************************************************************
FUNCTION: InitInstance(HANDLE, int)
PURPOSE: Saves instance handle in global variable and creates main
window.
RETURNS: Status of CreateWindow() call.
****************************************************************************/
BOOL InitInstance(hInstance, nCmdShow)
HANDLE hInstance;
int nCmdShow;
{
FARPROC lpProcInstance;
HMENU hMenu;
hInst = hInstance;
hAccTable = LoadAccelerators(hInst, "HelpexAcc");
hWnd = CreateWindow(
"HelpexWClass",
"Help Example ",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
return (FALSE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
EnableMenuItem(GetSubMenu(GetMenu(hWnd), 1), IDM_CLEAR, MF_ENABLED);
MakeHelpPathName(szHelpFileName);
hHelpCursor = LoadCursor(hInst,"HelpCursor");
lpProcInstance = MakeProcInstance(FilterFunc,hInstance);
if (lpProcInstance == NULL)
return (FALSE);
lpFilterFunc = SetWindowsHook(WH_MSGFILTER,lpProcInstance);
/*
* Store menu handles in global variables so that we can compare
* them for context sensitive help later.
*/
hMenu = GetMenu(hWnd);
hMenuFile = GetSubMenu(hMenu, 0);
hMenuEdit = GetSubMenu(hMenu, 1);
hMenuHelp = GetSubMenu(hMenu, 2);
return (TRUE);
}
/****************************************************************************
FUNCTION: FilterFunc(int, WORD, DWORD)
PURPOSE: Checks for the F1 key being pressed while a menu
or dialog box is displayed.
MESSAGES:
WM_F1DOWN- User defined message posted to main window to indicate
F1 has been pressed.
****************************************************************************/
int FAR PASCAL FilterFunc(nCode, wParam, lParam)
int nCode;
WORD wParam;
DWORD lParam;
{
LPMSG lpmsg = (LPMSG)lParam;
if ((nCode == MSGF_DIALOGBOX || nCode == MSGF_MENU) &&
lpmsg->message == WM_KEYDOWN && lpmsg->wParam == VK_F1) {
PostMessage(hWnd, WM_F1DOWN, nCode, 0L);
}
DefHookProc(nCode, wParam, lParam, &lpFilterFunc);
return (FALSE);
}
/****************************************************************************
FUNCTION: MyWinHelp(HWND, LPSTR, WORD, DWORD)
PURPOSE: This function may be used instead of WinHelp to
make HELP_SETCONTENTS work better. By using MyWinHelp()
instead of WinHelp() everywhere, you may send
HELP_SETCONTENTS to set the contents and not bring up
Help, and use any WinHelp API (including HELP_CONTENTS)
without losing the contents that got set.
****************************************************************************/
BOOL MyWinHelp(hwnd, lpHelpfile, wCommand, dwData)
HWND hwnd;
LPSTR lpHelpfile;
WORD wCommand;
DWORD dwData;
{
static DWORD ctxContents = (DWORD)-1L;
if (wCommand == HELP_SETCONTENTS) {
ctxContents = dwData;
return (TRUE);
}
if (wCommand == HELP_CONTENTS && ctxContents != (DWORD)-1L) {
WinHelp(hwnd, lpHelpfile, HELP_CONTEXT, ctxContents);
}
else {
WinHelp(hwnd, lpHelpfile, wCommand, dwData);
}
if (wCommand != HELP_QUIT && ctxContents != (DWORD)-1L) {
WinHelp (hwnd, lpHelpfile, HELP_SETCONTENTS, dwData);
}
}
/****************************************************************************
FUNCTION: StartDialog(WORD)
PURPOSE: This function is used to start a dialog with context
sensitive help. It assumes that the dialog resource
id is the same as the number that has been mapped to
the help context.
****************************************************************************/
void StartDialog(lpDialogProc, wDlgId)
FARPROC lpDialogProc;
WORD wDlgId;
{
FARPROC lpInstanceProc;
dwCurrentHelpId = (DWORD) wDlgId;
lpInstanceProc = MakeProcInstance(lpDialogProc, hInst);
DialogBox(hInst,
MAKEINTRESOURCE(wDlgId),
hWnd,
lpInstanceProc);
FreeProcInstance(lpInstanceProc);
dwCurrentHelpId = HELPID_NONE;
}
/****************************************************************************
FUNCTION: DisplayError(WORD)
PURPOSE: This function is used to display an error message with context
sensitive help. It assumes that the error string resource
id is the same as the number that has been mapped to
the help context.
****************************************************************************/
void DisplayError(wErrId)
WORD wErrId;
{
char rgchBuf[ERRORSTRING_MAX_SIZE];
dwCurrentHelpId = (DWORD) wErrId;
LoadString(hInst, wErrId, rgchBuf, ERRORSTRING_MAX_SIZE);
MessageBox(hWnd, rgchBuf, "Help Example", MB_OK);
dwCurrentHelpId = HELPID_NONE;
}
/****************************************************************************
FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
PURPOSE: Processes window messages.
MESSAGES:
WM_COMMAND- Application menu item
WM_DESTROY- Destroy window
****************************************************************************/
long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
switch (message) {
case WM_SYSCOMMAND:
/* Are we in help mode (Shift-F1)? */
if (bHelp) {
dwCurrentHelpId =
(wParam == SC_RESTORE) ? (DWORD) HELPID_SYSRESTORE :
(wParam == SC_MOVE) ? (DWORD) HELPID_SYSMOVE :
(wParam == SC_SIZE) ? (DWORD) HELPID_SYSSIZE :
(wParam == SC_MINIMIZE) ? (DWORD) HELPID_SYSMINIMIZE :
(wParam == SC_MAXIMIZE) ? (DWORD) HELPID_SYSMAXIMIZE :
(wParam == SC_CLOSE) ? (DWORD) HELPID_SYSCLOSE :
(wParam == SC_TASKLIST) ? (DWORD) HELPID_SYSSWITCH :
(DWORD) HELPID_NONE;
if (dwCurrentHelpId == HELPID_NONE)
return (DefWindowProc(hWnd, message, wParam, lParam));
bHelp = FALSE;
WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwCurrentHelpId);
dwCurrentHelpId = HELPID_NONE;
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
case WM_COMMAND:
/* Are we in help mode (Shift-F1)? */
if (bHelp) {
bHelp = FALSE;
WinHelp(hWnd,szHelpFileName,HELP_CONTEXT, (DWORD)wParam);
return NULL;
}
switch (wParam) {
case IDM_NEW:
case IDM_OPEN:
case IDM_SAVE:
case IDM_SAVEAS:
case IDM_PRINT:
case IDM_UNDO:
case IDM_CUT:
case IDM_CLEAR:
case IDM_COPY:
case IDM_PASTE:
DisplayError(ERR_NOT_YET_IMPLEMENTED);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDM_HELP_CONTENTS:
WinHelp(hWnd,szHelpFileName,HELP_CONTENTS,0L);
break;
case IDM_HELP_KEYBOARD:
WinHelp(hWnd, szHelpFileName, HELP_COMMAND,
(DWORD)(LPSTR)"JumpID(`myhelp.hlp',`IDM_HELP_KEYBOARD')");
break;
case IDM_HELP_SEARCH:
WinHelp(hWnd,szHelpFileName,HELP_PARTIALKEY,(DWORD)(LPSTR)"");
break;
case IDM_HELP_HELP:
WinHelp(hWnd,szHelpFileName,HELP_HELPONHELP,0L);
break;
case IDM_ABOUT:
StartDialog(About, ABOUTBOX);
break;
case IDM_HELP_MULTIKEY:
StartDialog(Multikey, EDITMULTIKEY);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case WM_LBUTTONDOWN:
if (bHelp) {
bHelp = FALSE;
WinHelp( hWnd, szHelpFileName, HELP_CONTEXT,
(DWORD) HELPID_EDIT_WINDOW );
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
case WM_NCLBUTTONDOWN:
/* If we are in help mode (Shift-F1) then display context- */
/* sensitive help for non-client area. */
if (bHelp) {
dwCurrentHelpId =
(wParam == HTCAPTION) ? (DWORD) HELPID_TITLE_BAR :
(wParam == HTREDUCE) ? (DWORD) HELPID_MINIMIZE_ICON :
(wParam == HTZOOM) ? (DWORD) HELPID_MAXIMIZE_ICON :
(wParam == HTBOTTOM) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTBOTTOMLEFT) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTBOTTOMRIGHT) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTTOP) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTLEFT) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTRIGHT) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTTOPLEFT) ? (DWORD) HELPID_SIZING_BORDER :
(wParam == HTTOPRIGHT) ? (DWORD) HELPID_SIZING_BORDER :
(DWORD) HELPID_NONE;
if (dwCurrentHelpId == HELPID_NONE)
return (DefWindowProc(hWnd, message, wParam, lParam));
bHelp = FALSE;
WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwCurrentHelpId);
dwCurrentHelpId = HELPID_NONE;
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
case WM_KEYDOWN:
if (wParam == VK_F1) {
/* If Shift-F1, turn help mode on and set help cursor */
if (GetKeyState(VK_SHIFT)<0) {
bHelp = TRUE;
SetCursor(hHelpCursor);
return (DefWindowProc(hWnd, message, wParam, lParam));
}
/* If F1 without shift, then call up help main index topic */
else {
WinHelp(hWnd,szHelpFileName,HELP_CONTENTS,0L);
}
}
else if (wParam == VK_ESCAPE && bHelp) {
/* Escape during help mode: turn help mode off */
bHelp = FALSE;
SetCursor((HCURSOR)GetClassWord(hWnd,GCW_HCURSOR));
}
break;
case WM_MENUSELECT:
/*
* Set dwCurrentHelpId to the Help ID of the menu item that is
* currently selected.
*/
if (HIWORD(lParam) == 0) /* no menu selected */
dwCurrentHelpId = HELPID_NONE;
else if (lParam & MF_POPUP) { /* pop-up selected */
if ((HMENU)wParam == hMenuFile)
dwCurrentHelpId = HELPID_FILE;
else if ((HMENU)wParam == hMenuEdit)
dwCurrentHelpId = HELPID_EDIT;
else if ((HMENU)wParam == hMenuHelp)
dwCurrentHelpId = HELPID_HELP;
else
dwCurrentHelpId = HELPID_SYSTEM;
}
else /* menu item selected */
dwCurrentHelpId = wParam;
break;
case WM_F1DOWN:
/* If there is a current help context, then */
/* display it */
if (dwCurrentHelpId != HELPID_NONE) {
DWORD dwHelp = dwCurrentHelpId;
/*******************************************
To provide context sensitive help for
individual controls in your dialog boxes,
include the following code:
if (wParam == MSGF_DIALOGBOX) {
WORD wID = GetWindowWord(GetFocus(), GWW_ID);
if (wID != IDOK && wID != IDCANCEL)
dwHelp = (DWORD)wID;
}
********************************************/
WinHelp(hWnd, szHelpFileName, HELP_CONTEXT, dwHelp);
/*
* This call is used to remove the highlighting from
* the system menu, if necessary.
*/
DrawMenuBar(hWnd);
}
break;
case WM_SETCURSOR:
/*
* In help mode it is necessary to reset the cursor in response
* to every WM_SETCURSOR message.Otherwise, by default, Windows
* will reset the cursor to that of the window class.
*/
if (bHelp) {
SetCursor(hHelpCursor);
break;
}
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
case WM_INITMENU:
if (bHelp) {
SetCursor(hHelpCursor);
}
return (TRUE);
case WM_DESTROY:
WinHelp(hWnd,szHelpFileName,HELP_QUIT,0L);
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (NULL);
}
/****************************************************************************
FUNCTION: About(HWND, UINT, WPARAM, LPARAM)
PURPOSE: Processes messages for "About" dialog box
MESSAGES:
WM_INITDIALOG - Initialize dialog box
WM_COMMAND- Input received
****************************************************************************/
BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
switch (message) {
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
if (wParam == IDOK) {
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}
/****************************************************************************
FUNCTION: Multikey(HWND, UINT, WPARAM, LPARAM)
PURPOSE: Processes messages for "Keyword" dialog box. Sends
HELP_MULTIKEY commands with the keyword entered in
the edit box.
MESSAGES:
WM_INITDIALOG - Initialize dialog box
WM_COMMAND- Input received
****************************************************************************/
BOOL FAR PASCAL Multikey(hDlg, message, wParam, lParam)
HWND hDlg;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
char rgchBuf[sizeof(MULTIKEYHELP) + MULTIKEY_MAX_SIZE];
MULTIKEYHELP FAR * lpMultikey;
switch (message) {
case WM_INITDIALOG:
SendDlgItemMessage(hDlg, IDEDITMULTIKEY, WM_SETTEXT, 0, (DWORD)(LPSTR)"Multikey");
return (TRUE);
case WM_COMMAND:
switch (wParam) {
case IDOK:
lpMultikey = (MULTIKEYHELP FAR *) rgchBuf;
lpMultikey->mkKeylist = 'M';
SendDlgItemMessage(hDlg, IDEDITMULTIKEY, WM_GETTEXT,
MULTIKEY_MAX_SIZE, (DWORD)(LPSTR)lpMultikey->szKeyphrase);
lpMultikey->mkSize =
sizeof(MULTIKEYHELP) + lstrlen(lpMultikey->szKeyphrase);
WinHelp(hWnd, szHelpFileName, HELP_MULTIKEY, (DWORD)lpMultikey);
/* Fall through: */
case IDCANCEL:
EndDialog(hDlg, TRUE);
return (TRUE);
}
}
return (FALSE);
}
/****************************************************************************
FUNCTION: MakeHelpPathName
PURPOSE: HelpEx assumes that the .HLP help file is in the same
directory as the HelpEx executable.This function derives
the full path name of the help file from the path of the
executable.
****************************************************************************/
void MakeHelpPathName(szFileName)
char * szFileName;
{
char * pcFileName;
int nFileNameLen;
nFileNameLen = GetModuleFileName(hInst,szFileName,EXE_NAME_MAX_SIZE);
pcFileName = szFileName + nFileNameLen;
while (pcFileName > szFileName) {
if (*pcFileName == '\\' || *pcFileName == ':') {
*(++pcFileName) = '\0';
break;
}
nFileNameLen--;
pcFileName--;
}
if ((nFileNameLen+13) < EXE_NAME_MAX_SIZE) {
lstrcat(szFileName, "helpex.hlp");
}
else {
lstrcat(szFileName, "?");
}
return;
}